module aru_psb_rdgen (
    input logic                   clk,
    input logic                   rst_n,
          aru_psb_rdgen_cfg_if.in u_aru_cfg_if,
          psb_rd_req_if.out       u_psb_rd_req_if,
          aru_psb_dat_fp32_if.in  u_aru_psb_dat_fp32_if,
          aru_payload_if.out      u_aru_payload_if
);
    aru_psb_rdgen_cfg_if u_aru_crd_gen_cfg_if ();
    aru_psb_rdgen_cfg_if u_aru_addr_calc_cfg_if ();
    aru_sdb_if u_aru_sdb_from_crd_gen_if ();
    aru_idx_if u_aru_idx_to_addr_calc_if ();
    aru_sdb_if u_aru_sdb_to_sdb_fifo_if ();
    aru_psb_dat_bf16_if u_aru_psb_dat_bf16_if ();

    aru_psb_rdgen_cfg_pipe u_aru_cfg_pipe (
        .clk                   (clk),
        .rst_n                 (rst_n),
        .u_aru_cfg_if          (u_aru_cfg_if),
        .u_aru_crd_gen_cfg_if  (u_aru_crd_gen_cfg_if),
        .u_aru_addr_calc_cfg_if(u_aru_addr_calc_cfg_if)
    );

    aru_psb_rdgen_crd_gen u_aru_crd_gen (
        .clk         (clk),
        .rst_n       (rst_n),
        .u_aru_cfg_if(u_aru_crd_gen_cfg_if),
        .u_aru_sdb_if(u_aru_sdb_from_crd_gen_if),
        .u_aru_idx_if(u_aru_idx_to_addr_calc_if)
    );

    aru_psb_rdgen_addr_calc u_aru_addr_calc (
        .clk                      (clk),
        .rst_n                    (rst_n),
        .u_aru_idx_if             (u_aru_idx_to_addr_calc_if),
        .u_aru_cfg_if             (u_aru_addr_calc_cfg_if),
        .u_aru_sdb_from_crd_gen_if(u_aru_sdb_from_crd_gen_if),
        .u_aru_sdb_to_sdb_fifo_if (u_aru_sdb_to_sdb_fifo_if),
        .u_psb_rd_req_if          (u_psb_rd_req_if)
    );

    aru_sdb_t sdb;
    logic sdb_fifo_empty, sdb_fifo_full;
    common_fifo #(
        .DATA_WIDTH($bits(aru_sdb_t)),
        .DEPTH(4)
    ) u_sdb_fifo (
        .clk    (clk),
        .rst_n  (rst_n),
        .wr_en  (u_aru_sdb_to_sdb_fifo_if.vld),
        .wr_data(u_aru_sdb_to_sdb_fifo_if.pld),
        .rd_en  (u_aru_payload_if.rdy && ~dat_fifo_empty),
        .rd_data(sdb),
        .full   (sdb_fifo_full),
        .empty  (sdb_fifo_empty)
    );

    aru_psb_rdgen_conv u_aru_psb_rdgen_conv (
        .clk    (clk),
        .rst_n  (rst_n),
        .psb_in (u_aru_psb_dat_fp32_if),
        .psb_out(u_aru_psb_dat_bf16_if)
    );

    aru_dat_t dat;
    logic dat_fifo_empty, dat_fifo_full;
    common_fifo #(
        .DATA_WIDTH($bits(aru_dat_t)),
        .DEPTH(4)
    ) u_dat_fifo (
        .clk    (clk),
        .rst_n  (rst_n),
        .wr_en  (u_aru_psb_dat_bf16_if.vld),
        .wr_data(u_aru_psb_dat_bf16_if.dat),
        .rd_en  (u_aru_payload_if.rdy && ~dat_fifo_empty),
        .rd_data(dat),
        .full   (dat_fifo_full),
        .empty  (dat_fifo_empty)
    );

    assign u_aru_payload_if.vld         = ~dat_fifo_empty;
    assign u_aru_payload_if.dat         = dat;
    assign u_aru_payload_if.sdb         = sdb;
    assign u_aru_sdb_to_sdb_fifo_if.rdy = ~sdb_fifo_full;

endmodule
